#!/sbin/openrc-run

name=moproxy

description="A transparent TCP to SOCKSv5/HTTP proxy."

extra_started_commands="enable disable reload"
description_enable="Start redirecting the network traffic to the HTTP proxy."
description_disable="Stop redirecting the network traffic to the HTTP proxy."
description_reload="Reload the proxy list."

# TCP Listen address
: ${host:=${MOPROXY_HOST:-"::"}}
# TCP Listen port
: ${port:=${MOPROXY_PORT:-"2080"}}
# List of backend proxy servers
: ${proxy_list:=${MOPROXY_PROXYLIST:-"/etc/moproxy/proxy.ini"}}
# Additional arguments to pass to moproxy
: ${moproxy_args:=${MOPROXY_ARGS:-""}}
# Override this argument to disable the use of TLS SNI
: ${moproxy_remotedns:=${MOPROXY_REMOTE_DNS:-"--remote-dns"}}
# Comma-separated list of port traffic to redirect to moproxy
: ${ports_redirected:=${MOPROXY_REDIRECTED_PORT:-"80,443"}}
# Comma-separated list of hostname to not redirect to the proxy
: ${noproxy_rules:=${MOPROXY_NOPROXY:-"0.0.0.0/8,10.0.0.0/8,127.0.0.0/8,169.254.0.0/16,172.16.0.0/12,192.168.0.0/16,224.0.0.0/4,240.0.0.0/4"}}

command="'${MOPROXY_BINARY:-/usr/sbin/moproxy}'"
command_args="--host ${host} --port ${port} ${moproxy_remotedns} --list ${proxy_list} ${moproxy_args}"
command_background="yes"
pidfile="/run/${name}.pid"

MOPROXY_LOGFILE="${MOPROXY_LOGFILE:-${LOG_DIR:-/var/log}/${RC_SVCNAME}.log}"
output_log="'${MOPROXY_LOGFILE}'"
error_log="'${MOPROXY_LOGFILE}'"

iptables_redirect_to_moproxy_chain() {
	iptables --table nat --$1 $2 --protocol tcp --match multiport --dports "${ports_redirected}" --jump MOPROXY
}

iptables_redirect() {
	iptables --table nat --append MOPROXY --protocol tcp --jump REDIRECT --to-port "${port}"
}

iptables_accept() {
	iptables --table nat --append MOPROXY --protocol tcp --destination "$1" --jump ACCEPT
}

add_noproxy_rules() {
	for i in ${noproxy_rules//,/ }
	do
		iptables_accept "$i"
	done
}

enable_redirection_to_moproxy_chain() {
	if ! iptables_redirect_to_moproxy_chain check $1 &> /dev/null
	then
		iptables_redirect_to_moproxy_chain append $1
	else
		einfo "Rule already in table"
	fi
}

disable_redirection_to_moproxy_chain() {
	while iptables_redirect_to_moproxy_chain check $1  &> /dev/null
	do
		iptables_redirect_to_moproxy_chain delete $1
	done
}

create_moproxy_chain() {
	iptables --table nat --new MOPROXY
}

delete_moproxy_chain() {
	iptables --table nat --flush MOPROXY
	iptables --table nat --delete-chain MOPROXY
}

depend() {
	after iptables ip6tables
}

enable() {
	einfo "Starting the iptables rules to start redirection of ports ${ports_redirected} to ${name}"
	create_moproxy_chain
	add_noproxy_rules
	iptables_redirect
	enable_redirection_to_moproxy_chain OUTPUT
	enable_redirection_to_moproxy_chain PREROUTING
}

disable() {
	einfo "Removing all the iptables rules to stop redirection to ${name}"
	disable_redirection_to_moproxy_chain PREROUTING
	disable_redirection_to_moproxy_chain OUTPUT
	delete_moproxy_chain
}

start_post() {
	enable
}

stop_pre() {
	disable
}

reload() {
	ebegin "Reloading ${name}"
	start-stop-daemon --signal HUP --pidfile "$pidfile"
	iptables --table nat --flush MOPROXY
	add_noproxy_rules
	iptables_redirect
}
